package com.csu.common.utils;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * 异常日志输出的工具类
 * 
 * @author jtz
 */
public class ExceptionUtil
{

    private static final Logger EXCEPTIONUTIL_LOGGER = Logger.getLogger(ExceptionUtil.class);

    /**
     * 记录异常日志
     * 
     * @param e
     * @param logger
     */
    public static void log(Exception e, Logger logger)
    {
        log(e, logger, null);
    }

    /**
     * 记录异常日志
     * 
     * @param e
     * @param logger
     * @param logMap
     *            日志参数
     */
    public static void log(Exception e, Logger logger, Map<String, String> logMap)
    {
        if (e != null && "logOff".equals(e.getMessage()))
        {
            return;
        }
        if (logMap == null)
        {
            logMap = new HashMap<String, String>();
        }
        if (e != null)
        {
            logMap.put("exceptionMessage", e.getMessage());// 增加message属性
            logMap.put("exception", getStackTrace(e));// 增加exception属性
            logMap.put("exceptionName", e.getCause() != null ? e.getCause().getClass().getName() : e.getClass().getName());// 增加exceptionName属性
        }
        logger.error("[expresslog] " + "[" + DateUtil.getDateFormatter() + "] " + JsonUtil.toJSONString(logMap));
    }

    public static void logInfo(Logger logger, String exception, String exceptionName)
    {
        Map<String, String> logMap = new HashMap<String, String>();
        logMap.put("exception", exception);// 增加exception属性
        logMap.put("exceptionName", exceptionName);// 增加exceptionName属性
        logger.error("[expresslog] " + "[" + DateUtil.getDateFormatter() + "] " + JsonUtil.toJSONString(logMap));
    }

    /**
     * 打印完整的异常堆栈信息
     * 
     * @author jintianzhang
     * @param e
     * @return 一行打印的异常
     */
    public static String getStackTrace(Exception e)
    {
        StringWriter sw = null;
        PrintWriter pw = null;
        try
        {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        }
        finally
        {
            if (sw != null)
            {
                try
                {
                    sw.close();
                }
                catch (IOException e1)
                {
                    EXCEPTIONUTIL_LOGGER.error("ExceptionUtil getStackTrace: close StringWriter error!", e1);
                }
            }
            if (pw != null)
            {
                pw.close();
            }
        }
        return sw.toString();
    }

    /**
     * get root cause
     * 
     * @param e
     * @return
     */
    public static Throwable getRootCause(Throwable e)
    {
        Throwable cause = e;
        while (true)
        {
            if (cause.getCause() == null)
            {
                break;
            }
            cause = cause.getCause();
        }
        return cause;
    }
}
